#!/usr/bin/env python3
import argparse
import pathlib
import sys
import yaml


# Aliases makes this YAML unreadable
# https://ttl255.com/yaml-anchors-and-aliases-and-how-to-disable-them/
class NoAliasDumper(yaml.SafeDumper):
    def ignore_aliases(self, data):
        return True


def parse_args(trees):
    parser = argparse.ArgumentParser(description="Generate TuxSuite YML.")
    parser.add_argument("tree",
                        help="The git repo and ref to filter in.",
                        choices=[tree["name"] for tree in trees])
    return parser.parse_args()


def get_config():
    # Trusted input.
    # https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation
    return yaml.load(sys.stdin, Loader=yaml.FullLoader)


def get_repo_ref(config, tree_name):
    for tree in config["trees"]:
        if tree["name"] == tree_name:
            return tree["git_repo"], tree["git_ref"]


def emit_tuxsuite_yml(config, tree):
    print("# DO NOT MODIFY MANUALLY!")
    print("# This file has been autogenerated by invoking:")
    print(
        "# $ ./generate_tuxsuite.py < generator.yml {} > tuxsuite/{}.tux.yml".
        format(tree, tree))
    print("# Invoke tuxsuite via:")
    print(
        "# $ tuxsuite build-set --set-name defconfigs --json-out builds.json --tux-config tuxsuite/{}.tux.yml"
        .format(tree))
    tuxsuite_buildset = {
        'sets': [
            {
                'name': 'defconfigs',
                'builds': [],
            }
        ]
    } # yapf: disable
    repo, ref = get_repo_ref(config, tree)
    ci_folder = pathlib.Path(__file__).resolve().parent
    with open(ci_folder.joinpath("LLVM_TOT_VERSION")) as f:
        max_version = int(f.read())
    defconfigs = []
    allconfigs = []
    for build in config["builds"]:
        if build["git_repo"] == repo and build["git_ref"] == ref:
            arch = build["ARCH"] if "ARCH" in build else "x86_64"
            toolchain = "clang-"
            toolchain += "nightly" if build[
                "llvm_version"] == max_version else str(build["llvm_version"])

            current_build = {
                "git_repo": build["git_repo"],
                "git_ref": build["git_ref"],
                "target_arch": arch,
                "toolchain": toolchain,
                "kconfig": build["config"],
                "targets": build["targets"]
            }
            if "kernel_image" in build:
                current_build.update({"kernel_image": build["kernel_image"]})
            if "make_variables" in build:
                current_build.update(
                    {"make_variables": build["make_variables"]})

            if "defconfig" in str(build["config"]):
                defconfigs.append(current_build)
            else:
                allconfigs.append(current_build)

    tuxsuite_buildset["sets"][0]["builds"] = defconfigs
    if allconfigs:
        tuxsuite_buildset["sets"] += [{
            "name": "allconfigs",
            "builds": allconfigs
        }]
    print(
        yaml.dump(tuxsuite_buildset,
                  Dumper=NoAliasDumper,
                  width=1000,
                  sort_keys=False))


if __name__ == "__main__":
    # The list of valid trees come from the input, so we parse the input, then
    # check command line flags.
    config = get_config()
    args = parse_args(config["trees"])
    emit_tuxsuite_yml(config, args.tree)
